package cn.lj.login.service.service.impl;

import cn.lj.common.cahce.LoginCahce;
import cn.lj.common.enums.RestResult;
import cn.lj.common.enums.RestResultEmum;
import cn.lj.common.json.JacksonUtil;
import cn.lj.common.redis.constant.RedisConstant;
import cn.lj.common.util.BeanCopierUtil;
import cn.lj.common.util.EncryptUtil;
import cn.lj.login.mapper.mapper.LoginMapper;
import cn.lj.login.mapper.pojo.SmallMiForgetPassword;
import cn.lj.login.mapper.pojo.SmallMiUser;
import cn.lj.login.mapper.qo.SmallMiLoginNumberQO;
import cn.lj.login.mapper.qo.SmallMiUserLoginQO;
import cn.lj.login.service.bo.SmallMiForgetPasswordBO;
import cn.lj.login.service.bo.SmallMiLoginNumberBO;
import cn.lj.login.service.bo.SmallMiUserLoginBO;
import cn.lj.login.service.service.LoginService;
import cn.zy.common.alisms.dto.AUTHCode;
import cn.zy.common.redis.RedisServie;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @Description: LoginServiceImpl
 * @author: lijie
 * @date: 2021年07月16日 下午 12:24:9
 */
@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private RedisServie redisServie;
    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private Client client;

    /**
     * 功能描述: 登录成功或失败验证
     *
     * @param smallMiUserLoginBO:
     * @auther: lijie
     * @date: 2021/7/16 下午 03:01:55
     * @return: cn.lj.common.enums.RestResult<java.lang.Void>
     */
    @Override
    public RestResult<Void> inlogin(SmallMiUserLoginBO smallMiUserLoginBO) {
        SmallMiUser smallMiUser = BeanCopierUtil.copyObj(smallMiUserLoginBO, SmallMiUser.class);
        //逻辑代码
        //判断拿到的id，邮箱，手机号和密码是否为空
        if ((smallMiUser.getMi_id() == null && smallMiUser.getMi_pass_word() == null) ||
                (smallMiUser.getMi_email() == null && smallMiUser.getMi_pass_word() == null) ||
                (smallMiUser.getMi_phone() == null && smallMiUser.getMi_pass_word() == null)) {
            return new RestResult<>(RestResultEmum.LOGIN_NULL_ERROR.code, RestResultEmum.LOGIN_NULL_ERROR.msg);
        }
        //把拿到的密码进行加密
        String s = EncryptUtil.MD5(smallMiUser.getMi_pass_word());
        System.out.println(s);
        //把传入的密码赋值到实体类
        smallMiUser.setMi_pass_word(s);
        //判断数据库中是否有该用户
        SmallMiUserLoginQO inlogin = loginMapper.inlogin(smallMiUser);
        //如果查的数据为空
        if (inlogin == null)
            return new RestResult<Void>(RestResultEmum.LOGIN_ERROR.code, RestResultEmum.LOGIN_ERROR.msg);
        if (inlogin.getMi_id().equals(smallMiUser.getMi_id()) || inlogin.getMi_email().equals(smallMiUser.getMi_email()) || inlogin.getMi_phone().equals(smallMiUser.getMi_phone())) {
            //判断密码是否正确
            if (inlogin.getMi_pass_word().equals(s)) {
                //把用户信息放入本地线程
                LoginCahce.setSmallMiUser(smallMiUser);
                return new RestResult<Void>(RestResultEmum.SUCCESS.code, RestResultEmum.SUCCESS.msg);
            }
        } else {
            //如果不存在返回错误信息
            return new RestResult<Void>(RestResultEmum.LOGIN_NULL_ERROR.code, RestResultEmum.LOGIN_NULL_ERROR.msg);
        }
        return new RestResult<Void>(RestResultEmum.LOGIN_NULL_ERROR.code, RestResultEmum.LOGIN_NULL_ERROR.msg);
    }

    /**
     * 功能描述: 获取验证码
     *
     * @param number:传入手机号
     * @auther: lijie
     * @date: 2021/7/16 下午 05:56:9
     * @return: cn.lj.common.enums.RestResult<java.lang.Void>
     */
    @Override
    public RestResult<Void> inloginyzm(String number) throws Exception {
        //判断手机号是否为空
        if (number == null || number == "")
            return new RestResult<Void>(RestResultEmum.NUMBER_ERROR.code, RestResultEmum.NUMBER_ERROR.msg);
        //查询数据库中该手机号是否存在
        String numbers = loginMapper.inloginNumber(number);
        //判断数据库中是否有该手机号
        if (numbers == null || numbers.length() == 0)
            return new RestResult<Void>(RestResultEmum.NUMBERS_ERROR.code, RestResultEmum.NUMBERS_ERROR.msg);
        //创建第三方验证码的对象
        SendSmsRequest sendsmsrequest = new SendSmsRequest();
        //获取接收短信的手机号
        sendsmsrequest.setPhoneNumbers(number);
        sendsmsrequest.setSignName("BaseAdmin管理");
        sendsmsrequest.setTemplateCode("SMS_218290669");
        //先拿一下reids中的key，看看有没有，如果有直接使用，没有就创建
        AUTHCode obj = redisServie.getObj(RedisConstant.REDIS_YZM + number, AUTHCode.class);
        //如果reids有验证码了
        if (obj != null) {
            //给验证码失效时间再重置为5分钟
            redisServie.expire(RedisConstant.REDIS_YZM + number, 60 * 5L);
            //把拿到的的对象转成json传入并发送短信
            String s = JacksonUtil.toJsonStr(obj);
            sendsmsrequest.setTemplateParam(s);
            client.sendSms(sendsmsrequest);
            return new RestResult<>(RestResultEmum.YZM_SUCCESS.code, RestResultEmum.YZM_SUCCESS.msg);
        }
        //生成一个6位数的验证码
        String authCode = EncryptUtil.getAuthCode(6);
        //给实体类对象赋值
        AUTHCode authCode1 = new AUTHCode();
        authCode1.setCode(authCode);
        //把这个对象转成json
        String s = JacksonUtil.toJsonStr(authCode1);
        sendsmsrequest.setTemplateParam(s);
        //redis存放验证码，设置过期时间为5分钟，（主键为手机号，值为验证码）
        redisServie.setObj(RedisConstant.REDIS_YZM + number, authCode1, 60 * 5L);
        client.sendSms(sendsmsrequest);
        return new RestResult<Void>(RestResultEmum.YZM_SUCCESS.code, RestResultEmum.YZM_SUCCESS.msg);
    }

    /**
     * 功能描述: 使用手机号验证码进行登录
     *
     * @param smallMiLoginNumberBO:
     * @auther: lijie
     * @date: 2021/7/16 下午 07:33:42
     * @return: cn.lj.common.enums.RestResult<java.lang.Void>
     */
    @Override
    public RestResult<Void> inloginnumber(SmallMiLoginNumberBO smallMiLoginNumberBO) {
        //拿到数据进行非空校验
        if (smallMiLoginNumberBO.getYzm() == null || smallMiLoginNumberBO.getPhone() == null) {
            return new RestResult<>(RestResultEmum.YZMS_ERROR.code, RestResultEmum.YZMS_ERROR.msg);
        }
        //从redis中拿到code和验证码
        Object o = redisServie.getObj(RedisConstant.REDIS_YZM + smallMiLoginNumberBO.getPhone());
        //判断redis中是否有验证码
        if (o == null) return new RestResult<>(RestResultEmum.YZMS_ERROR.code, RestResultEmum.YZMS_ERROR.msg);
        //拿到具体验证码值
        Map map = (Map) o;
        //判断拿到的验证码是否正确
        if (!smallMiLoginNumberBO.getYzm().equals(map.get("code")))
            return new RestResult<>(RestResultEmum.YZMS_ERROR.code, RestResultEmum.YZMS_ERROR.msg);
        return new RestResult<Void>();
    }

    /**
     * 功能描述: 修改密码
     *
     * @param smallMiForgetPasswordBO:
     * @auther: lijie
     * @date: 2021/7/20 上午 08:48:7
     * @return: cn.lj.common.enums.RestResult<java.lang.Void>
     */
    @Override
    public RestResult<Void> ForgetPassword(SmallMiForgetPasswordBO smallMiForgetPasswordBO) {
        SmallMiLoginNumberBO smallMiLoginNumberBO = BeanCopierUtil.copyObj(smallMiForgetPasswordBO, SmallMiLoginNumberBO.class);
        //调用本类验证验证码方法
        RestResult<Void> inloginnumber = inloginnumber(smallMiLoginNumberBO);
        if (inloginnumber.getCode().equals(RestResultEmum.YZMS_ERROR.code)) {
            return new RestResult<>(RestResultEmum.YZMS_ERROR.code, RestResultEmum.YZMS_ERROR.msg);
        }
        //修改密码
        //通过手机号查询全部数据
        String s = loginMapper.inloginNumber(smallMiLoginNumberBO.getPhone());
        if (s == null) return new RestResult<>(RestResultEmum.NUMBER_ERROR.code, RestResultEmum.NUMBER_ERROR.msg);
        //拿到的数据进行修改密码
        SmallMiForgetPassword smallMiForgetPassword = BeanCopierUtil.copyObj(smallMiForgetPasswordBO, SmallMiForgetPassword.class);
        //拿到密码进行加密
        String pass = EncryptUtil.MD5(smallMiForgetPasswordBO.getPassword());
        //赋值
        smallMiForgetPassword.setMi_pass_word(pass);
        smallMiForgetPassword.setMi_phone(smallMiForgetPasswordBO.getPhone());
        int i = loginMapper.ForgetPassword(smallMiForgetPassword);
        if (i != 1) {
            return new RestResult<>(RestResultEmum.EDIT_ERROR.code, RestResultEmum.EDIT_ERROR.msg);
        }
        return new RestResult<>(RestResultEmum.SUCCESS.code, RestResultEmum.SUCCESS.msg);
    }
}
